#查询模块
import os
import struct

#index 查询的地址块编号
def queryindex(index):
    """
    :param index:x(int)
    """
    #数据文件名称
    dataFile = ['gpw_v4_population_count_rev11_2020_30_sec_1.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_2.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_3.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_4.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_5.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_6.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_7.asc',
                'gpw_v4_population_count_rev11_2020_30_sec_8.asc'
                ]
    #获取当前路径
    curPath = os.getcwd()
    #待访问文件名字
    curFileName = dataFile[index-1]
    #合成读取待读取文件路径
    readPath = curPath + '\\gpw-v4-population-count-rev11_2020_30_sec_asc\\' + curFileName
    #读取
    freadPath = open(readPath)
    #获取前六行概览信息
    linencols = freadPath.readline()
    linenrows = freadPath.readline()
    linexllcorner = freadPath.readline()
    lineyllcorner = freadPath.readline()
    linecellsize = freadPath.readline()
    lineNODATA_value = freadPath.readline()
    
    print(f'{linencols}{linenrows}{linexllcorner}{lineyllcorner}{linecellsize}{lineNODATA_value}')

    #数据信息读取
    countLine = 0 #记录行数
    linedata = freadPath.readline()

    #linedata空退出
    while linedata:
        #分割为10800个数据 List Type(str)
        splitList = linedata.split( )
        #继续读取
        linedata = freadPath.readline()
        countLine = countLine+1
    print(f'{countLine} {len(splitList)}')
    freadPath.close()

#根据坐标获取地图块序号
def getCoordinateBlock(coordinate):
    '''
    :param coordinate:[x,y]
    '''
    x = coordinate[0]
    y = coordinate[1]
    #1 2 3 4
    #5 6 7 8
    if x < -180 or x > 180 or y < -90 or y > 90:
        return -1
    #上半区1 2 3 4
    if y <=90 and y >=0:
        if x >= -180 and x < -90:
            return 1
        elif x >= -90 and x < 0:
            return 2
        elif x >= 0 and x < 90:
            return 3
        elif x >= 90 and x <= 180:
            return 4
    #下半区
    else:
        if x >= -180 and x < -90:
            return 5
        elif x >= -90 and x < 0:
            return 6
        elif x >= 0 and x < 90:
            return 7
        elif x >= 90 and x <= 180:
            return 8

#判断一个点是否在多边形内部
def is_in_poly(p, poly):
    """
    :param p: [x, y]
    :param poly: [[], [], [], [], ...]
    :return:
    """
    #(px,py) 判断点
    px, py = p
    is_in = False
    for i, corner in enumerate(poly):
        next_i = i + 1 if i + 1 < len(poly) else 0
        #(x1,y1) (x2,y2)是多边形线段端点
        x1, y1 = corner
        x2, y2 = poly[next_i]
        if (x1 == px and y1 == py) or (x2 == px and y2 == py):  # if point is on vertex
            is_in = True
            break
        if min(y1, y2) < py <= max(y1, y2):  # find horizontal edges of polygon
            #该点介于(y1,y2)之间
            x = x1 + (py - y1) * (x2 - x1) / (y2 - y1)
            #(x,py)是过(px,py)作平行x轴的直线与直线(x1,y1)(x2,y2)的交点
            if x == px:  #(x,py)在线段(x1,y1)(x2,y2)上 注:先前已经确定该点介于(y1,y2)之间
                is_in = True
                break
            elif x > px:  # if point is on left-side of line
                is_in = not is_in
    return is_in

#根据多边形进行数据的查询
def queryInfo(poly):
    print(f'begin my query')
    print(poly)
    p = [30.0,11.0]
    print(is_in_poly(p,poly))
    return "get it"

#---------------1.9号-----------------
#给定坐标,返回其是第cnum个小块
def getCnumByCoordinate(x,y):
    '''
    para x:float 横坐标
    para y:float 纵坐标
    '''
    #10800*10800 每一块的小块数目
    block_num = 116640000
    #(x,y)所在的块数
    xy_block = 0
    #xy_block块左上角坐标
    xy_left = 0
    xy_top = 0
    #非法,退出
    if x < -180 or x > 180 or y < -90 or y > 90:
        print(f'非法输入坐标')
        return -1
    #上半区1 2 3 4
    if y <=90 and y >=0:
        if x >= -180 and x < -90:
            xy_block = 1
            xy_left = -180
            xy_top = 90
        elif x >= -90 and x < 0:
            xy_block = 2
            xy_left = -90
            xy_top = 90
        elif x >= 0 and x < 90:
            xy_block = 3
            xy_left = 0
            xy_top = 90
        elif x >= 90 and x <= 180:
            xy_block = 4
            xy_left = 90
            xy_top = 90
    #下半区
    else:
        if x >= -180 and x < -90:
            xy_block = 5
            xy_left = -180
            xy_top = 0
        elif x >= -90 and x < 0:
            xy_block = 6
            xy_left = -90
            xy_top = 0
        elif x >= 0 and x < 90:
            xy_block = 7
            xy_left = 0
            xy_top = 0
        elif x >= 90 and x <= 180:
            xy_block = 8
            xy_left = 90
            xy_top = 0
    #块偏移+块内偏移 120*10800 = 1296000
    # print(f'块偏移量:{(xy_block-1)*block_num}')
    # print(f'块内偏移 ry:{xy_top-y} rx:{x-xy_left}')
    # print(f'块内偏移:{int((xy_top-y)*1296000) + int((x-xy_left)*120+1)}')
    offset1 = (xy_block-1)*block_num
    offset2 = int((xy_top-y)*1296000)
    offset3 = int((x-xy_left)*120+1)
    # print(f'offset1:{offset1} offset23:{offset2+offset3}')
    # cnum = (xy_block-1)*block_num + int((xy_top-y)*129600) + int((x-xy_left)*120+1)
    cnum = offset1 + offset2 + offset3
    return cnum

#读取merge.dat中第offset个数字
def getDataByOffset(offset):
    '''
        para offset:int 二进制文件第offset个数字
        return num_float:float 查询的浮点数字
    '''
    f_bin = open('merge.dat','rb')
    f_bin.seek((offset-1)*4)
    num_byte = f_bin.read(4)
    num_float = struct.unpack('>f',num_byte)
    # print(f'num_float:{num_float}')
    f_bin.close()
    return num_float

#给定多边形 返回一个能够包裹它的矩形 右上角 左下角
def findRectangle(point_list):
    #右上角
    Rec_right = -1
    Rec_up = -1
    #左下角
    Rec_left = 999
    Rec_down = 999
    #遍历多边形 确定右上角和左下角坐标
    for i in range(len(point_list)):
        #右上角
        if Rec_right < point_list[i][0]:
            Rec_right = point_list[i][0]
        if(Rec_up < point_list[i][1]):
            Rec_up = point_list[i][1]
        #左下角
        if(Rec_left > point_list[i][0]):
            Rec_left = point_list[i][0]
        if(Rec_down > point_list[i][1]):
            Rec_down = point_list[i][1]
    ret = []
    ret.append([Rec_right,Rec_up])
    ret.append([Rec_left,Rec_down])
    return ret

#给定矩形 打印所有可以查询的点
def findPointByRectangle(Rec):
    '''
        para Rec:[[right,top],[left,bottom]]
        return ret : list
    '''
    #右上角
    Rec_right = Rec[0][0]
    Rec_up = Rec[0][1]
    #左下角
    Rec_left = Rec[1][0]
    Rec_down = Rec[1][1]
    #从左上角往右下角扫描
    x = Rec_left
    y = Rec_up
    #待返回列表
    ret = []
    color_num = 0
    while y >= Rec_down:
        x = Rec_left
        while x <= Rec_right:
            #计算当前是第多少个数字
            coffset = getCnumByCoordinate(x,y)
            cnumTuple = getDataByOffset(coffset)
            cnum = cnumTuple[0]
            # print(f'cnum:{cnum} type:{type(cnum)} cnum[0];{cnum[0]} type:{type(cnum[0])}')
            # exit(-1)
            if(cnum != -9999):
                # print(f'cnum:{cnum}')
                color_num = color_num+1
            ret.append(cnum)
            #右移一格
            x += 0.0083333333333333
        # print(f'append 一行 目前len = {len(ret)}')
        #下移一格
        y -= 0.0083333333333333
    print(f'color_num:{color_num}')
    return ret

        











